#include					<iostream>
#include					"player.h"

Player::Player() : _stream(NULL), _volume(1)
{
	_sample_rate = 48000;
	_frames_per_buffer = 480;
	_num_channels = 2;
//	_buffer.init();
}

Player::~Player()
{
	if (_stream)
		Pa_CloseStream(_stream);
}

static int					playCallback( const void *inputBuffer, void *outputBuffer,
                              unsigned long framesPerBuffer,
                              const PaStreamCallbackTimeInfo* timeInfo,
                              PaStreamCallbackFlags statusFlags,
                              void *userData)
{
	Player			*speaker = reinterpret_cast<Player *>(userData);

	return speaker->playCall((short *) outputBuffer);
}

int							Player::playCall(short *outputBuffer)
{
	if (!_buffer.empty())
	{
		size_t to_calc = _frames_per_buffer * _num_channels;
		SoundPacket	*sample = _buffer.front();
		_buffer.pop();
//		while (!_buffer.empty() && sample->ts < _buffer.front()->ts)
//		{
//			delete sample->sample;
//			delete sample;
//			sample = _buffer.front();
//			_buffer.pop();
//		}
		short	*input = sample->data();
		for (int i = 0; i < sample->len(); ++i)
		{
			outputBuffer[i] = input[i];
		}
	}
	else
		std::cout << "[WARNING] Sound buffer empty, can't keep up ?" << std::endl;
	return _status;
}

void						Player::setVolume(float volume)
{
	if (volume >= 0 && volume <= 1)
		_volume = volume;
}

void						Player::start()
{
	PaError		err;

	err = Pa_Initialize();
	if( err == paNoError )
	{
		_outputParameters.device = Pa_GetDefaultOutputDevice();
		if (_outputParameters.device > 0)
		{
			_outputParameters.channelCount = _num_channels;
		    _outputParameters.sampleFormat =  paInt16;
			_outputParameters.suggestedLatency = Pa_GetDeviceInfo(_outputParameters.device)->defaultHighOutputLatency;
		    _outputParameters.hostApiSpecificStreamInfo = NULL;
		   err = Pa_OpenStream(&_stream, NULL, &_outputParameters,
				_sample_rate, _frames_per_buffer, paClipOff,
				playCallback, this);
		   if (err != paNoError)
			   std::cout << "[CRITICAL] can't open stream" << std::endl;
		}
		else
			std::cout << "[CRITICAL] can't open audio device" << std::endl;
	}
	else
		std::cout << "[CRITICAL] can't initialize audio lib" << std::endl;
}

void						Player::stop()
{
	std::cout << "play [OFF]" << std::endl;
	_status = paComplete;
	Pa_StopStream(_stream);
}

void						Player::play()
{
	if(_stream)
	{
		std::cout << "play [ON]" << std::endl;
		_status = paContinue;
		while (!_buffer.empty())
			_buffer.pop();
		Pa_StartStream(_stream);
	}
	else
		std::cout << "error on play" << std::endl;
}

void						Player::write(SoundPacket* data, unsigned int stamp)
{
//	_mutex.lock();
//	ssample *sample = new ssample;

//	sample->sample = data->data();
//	sample->ts = stamp;
//	_buffer.push(sample);
//	_mutex.unlock();
}

void						Player::addSoundPacket(SoundPacket *input)
{
	_buffer.push(input);
}
